package main

import (
	"fmt"
  "strings"
  "time"
)

func Adder() func(int) int {
  var x int
  return func(d int) int {
    x += d
    return x
  }
}
func Adder2(base int) func(int) int {
  return func(d int) int {
    base += d
    return base
  }
}

func makeSuffixFunc(suffix string) func(string) string {
  return func(name string) string {
    if !strings.HasSuffix(name, suffix) {
      return name + suffix
    }
    return name
  }
}

func calc(base int)(func(int) int, func(int) int) {
  add := func(i int) int {
    base += i
    return base
  }

  sub := func(i int)int {
    base -= i
    return base
  }

  return add,sub
}

//========================================================

func testClosure1() {
  f := Adder()
  ret := f(1)
  fmt.Printf("f(1):ret=%d\n", ret)
  ret = f(20)
  fmt.Printf("f(20):ret=%d\n", ret)
  ret = f(100)
  fmt.Printf("f(100):ret=%d\n", ret)

  f1 := Adder()
  ret = f1(1)
  fmt.Printf("f1(1):ret=%d\n", ret)
  ret = f1(1000)
  fmt.Printf("f1(1000):ret=%d\n", ret)
}

func testClosure2() {
  tmp1 := Adder2(10)
  fmt.Println(tmp1(1), tmp1(2))
  tmp2 := Adder2(100)
  fmt.Println(tmp2(1), tmp2(2))
}

func testClosure3() {
  func1 := makeSuffixFunc(".bmp")
  func2 := makeSuffixFunc(".jpg")

  fmt.Println(func1("test"))
  fmt.Println(func2("test"))
}

func testClosure4(){
  f1,f2 := calc(10)
  fmt.Println(f1(1),f2(2))
  fmt.Println(f1(3),f2(4))
  fmt.Println(f1(5),f2(6))
  fmt.Println(f1(7),f2(8))
}

func testClosure5(){
  for i := 0; i < 5; i++ {
    go func(index int) {
      fmt.Println(index)
    }(i)
  }
  time.Sleep(time.Second)
}

func main() {
  //testClosure1()
/*
   f(1):ret=1
   f(20):ret=21
   f(100):ret=121
   f1(1):ret=1
   f1(1000):ret=1001
*/

  //testClosure2()
  /*
     11 13
     101 103
  */


  //testClosure3()
/*
   test.bmp
   test.jpg
*/

  //testClosure4()
/*
   11 9
   12 8
   13 7
   14 6
*/

  testClosure5()
}
